﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Exceptional;
using System;
using System.Data;
using System.Linq;
using System.Security.Claims;
using XW.Core;
using XW.Data;
using XW.Logging;

using XW.Utils;
using XW.Web.Framework.Permissions;

namespace XW.Web.Framework
{
	public class BaseController : Controller
	{
		public ILog L = LogProvider.GetCurrentClassLogger();

		public override void OnActionExecuting(ActionExecutingContext context)
		{
			base.OnActionExecuting(context);
			try
			{
				// 当前是否需要验证授权码
				var filters = context.ActionDescriptor.FilterDescriptors; //.Where(f => f.Filter is AuthorizeFilter || f.Filter is AllowAnonymousFilter).ToList();
				var needAuthory = false;
				if (filters.Count > 0)
				{
					foreach (var f in filters)
					{
						if (f.Filter is AuthorizeFilter)
						{
							needAuthory = true;
						}

						if (f.Filter is AllowAnonymousFilter)
						{
							needAuthory = false;
						}
					}
				}
				//bool needRemoting = true;
				//if (needAuthory)
				//{
				//    var cctionDescriptor = context.ActionDescriptor as Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor;
				//    if (cctionDescriptor != null)
				//    {
				//        var unNeedRemoting = cctionDescriptor.MethodInfo.GetCustomAttributes(typeof(UnNeedRemotingAttribute), true);
				//        if (unNeedRemoting.Length > 0)
				//        {
				//            needRemoting = false;
				//        }
				//    }
				//    if (needRemoting)
				//    {
				//        needRemoting = NeedRemotingCode(context.HttpContext);
				//    } 
				//}
				//// 检查当前是否需要验证远程授权码
				//if (needAuthory && needRemoting)
				//{
				//    string remote_code = this.UserInfo.remote_code;
				//    DateTime remote_end_date = CommonHelper.ToDateTime(this.UserInfo.remote_end_date, DateTime.MinValue);
				//    bool can_remote = CommonHelper.ToBool(this.UserInfo.can_remote, false);
				//    // 检查授权码
				//    if (!can_remote || remote_end_date.Date < DateTime.Now.Date || remote_code != this.RemoteCode)
				//    {
				//        context.Result = GetErrorResult("授权码过期或不正确，或者不允许远程授权，请联系管理员。");
				//        //  return GetErrorResult("授权码过期或不正确，或者不允许远程授权，请联系管理员。");
				//    }
				//}
				//else
				//{
				//}
			}
			catch (Exception ex)
			{
				try
				{
					if (context != null)
					{
						ex.LogAsync(context.HttpContext, customData: new Dictionary<string, string> { { "cusTace", ex.StackTrace } });
					}
				}
				catch (Exception)
				{

				}

			}

		}
		/// <summary>
		/// 检查是否需要授权码
		/// </summary>
		/// <param name="context"></param>
		/// <returns></returns>
		public bool NeedRemotingCode(HttpContext context)
		{
			string ip = context.GetUserIp();
			var userSafeList = ConfigHelper.GetAppBool("User:SafeList", false);  // 是否开启白名单
			this.L.Debug("路由：【{0}】 needAuthory:{1}, IP:{2},{3},是否开启用户IP地址白名单:{4}", context.Request.Path, true, ip, CommonHelper.IsPrivateNetwork(ip), userSafeList);

			var isPrivate = CommonHelper.IsPrivateNetwork(ip); // 是否局域网IP
			if (userSafeList && !isPrivate)
			{
				var ips = this.db.Sql("select ip from sys_safe_list(nolock) where data_status = 0").QueryMany<string>();
				if (ips.Contains(ip.Trim()))
				{
					return false;
				}
				return true;
			}
			else
			{
				return false;
			}
		}
		public IActionResult Xlsx()
		{
			return null;
		}
		public IActionResult Xlsx(byte[] data, string fileName)
		{
			return File(data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
		}
		public IActionResult Xlsx(DataTable dt, Dictionary<string, string> columns, string title)
		{
			return Xlsx(NPOIHelper.ExportXLSX(dt, columns, title), title + ".xlsx");
		}
		public IActionResult Xlsx(List<dynamic> dataList, Dictionary<string, string> columns, string title)
		{
			return Xlsx(NPOIHelper.ExportXLSX(dataList, columns, title), title + ".xlsx");
		}

		public IActionResult Xlsx(List<dynamic> dataList, List<ExcelColumn> columns, string title)
		{
			return Xlsx(NPOIHelper.ExportXLSX(dataList, columns, title), title + ".xlsx");
		}
		public IActionResult Xlsx(DataTable dt, List<ExcelColumn> columns, string title)
		{
			return Xlsx(NPOIHelper.ExportXLSX(dt, columns, title), title + ".xlsx");
		}
		#region 获取成功结果 GetSuccessResult
		/// <summary>
		/// 获取成功结果
		/// </summary>
		/// <returns></returns>
		public JsonResult GetSuccessResult()
		{
			return GetSuccessResult("操作成功！");
		}
		/// <summary>
		/// 获取成功结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetSuccessResult(string message)
		{
			return Json(new { resultCode = ResultCode.Success, message = message });
		}

		/// <summary>
		/// 获取返回结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="data"></param>
		/// <returns></returns>
		public JsonResult GetResultData(string code, object data)
		{
			return Json(new { resultCode = code, data = data });
		}

		/// <summary>
		/// 获取成功结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetSuccessResult(object data)
		{
			return Json(new { resultCode = ResultCode.Success, data = data });
		}
		/// <summary>
		/// 获取返回结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <param name="data"></param>
		/// <returns></returns>
		public JsonResult GetSuccessResult(string message, object data)
		{
			return Json(new { resultCode = ResultCode.Success, message = message, data = data });
		}
		#endregion

		#region 获取失败结果 GetErrorResult
		/// <summary>
		/// 获取失败结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetErrorResult()
		{
			return Json(new { resultCode = ResultCode.Error, message = "操作失败！" });
		}
		/// <summary>
		/// 获取失败结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetErrorResult(string message)
		{
			return Json(new { resultCode = ResultCode.Error, message = message });
		}
		/// <summary>
		/// 获取失败结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetErrorResult(string message, object parameters)
		{
			return Json(new { resultCode = ResultCode.Error, message = message, parameters = parameters });
		}

		/// <summary>
		/// 获取失败结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetErrorResultFormat(string messageformat, params object[] parameters)
		{
			return Json(new { resultCode = ResultCode.Error, message = string.Format(messageformat, parameters) });
		}
		/// <summary>
		/// 获取失败结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetErrorResult(Exception ex)
		{
			return Json(new { resultCode = ResultCode.Error, message = "操作失败！异常内容：" + ex.Message });
		}
		#endregion

		#region 获取返回结果
		/// <summary>
		/// 获取返回结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <returns></returns>
		public JsonResult GetResultMsg(string code, string message)
		{
			return Json(new { resultCode = code, message = message });
		}

		/// <summary>
		/// 获取返回结果
		/// </summary>
		/// <param name="code"></param>
		/// <param name="message"></param>
		/// <param name="data"></param>
		/// <returns></returns>
		public JsonResult GetResultObj(string code, string message, object data)
		{
			return Json(new { resultCode = code, message = message, data = data });
		}
		#endregion

		#region 受保护的方法
		/// <summary>
		/// 检查当前用户是否有某个权限
		/// </summary>
		/// <param name="permissionName"></param>
		/// <returns></returns>
		protected bool CheckPermission(string permissionName)
		{
			var service = HttpContext.RequestServices.GetRequiredService<IPermissionService>();
			string? userId = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_USER_ID);// 用户id
			var sup = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_SUP_ADMIN); // 是否是超级管理员
			if (sup == "1") return true;
			return service.CheckPermission(CommonHelper.ToInt64(userId), this.OrgId, permissionName);
		}

		protected IWebHostEnvironment Environment
		{

			get
			{
				var env = HttpContext.RequestServices.GetRequiredService<IWebHostEnvironment>();
				return env;
			}
		}
		#endregion
		#region db
		private IDbContext _db = null;
		public IDbContext db
		{
			get
			{
				if (_db == null)
				{
					_db = new DbContext().ConnectionStringName("Default", new SqlServerProvider());
				}
				return _db;
			}
		}
		public IDbContext getDb(string con)
		{
			return new DbContext().ConnectionString(con, new SqlServerProvider());
		}
		#endregion
		#region 用户信息

		/// <summary>
		/// 用户Id
		/// </summary>
		public long UserId
		{
			get
			{
				string? userId = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_USER_ID);
				if (userId.IsNullOrEmpty())
				{
					return 0;
				}
				else
				{
					return CommonHelper.ToInt64(userId);
				}
			}
		}
		/// <summary>
		/// 当前用户系统
		/// </summary> 
		public string UserSystem
		{
			get
			{

				string? s = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_SYSTEM);
				if (s.IsNullOrEmpty())
				{
					return "Default";
				}
				else
				{
					return s;
				}
			}
		}
		/// <summary>
		/// 是否超级用户
		/// </summary>
		public int IsSup
		{
			get
			{

				string? is_sup = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_SUP_ADMIN);
				if (is_sup.IsNullOrEmpty())
				{
					return 0;
				}
				else
				{
					return CommonHelper.ToInt(is_sup);
				}
			}
		}

		///// <summary>
		///// 授权码
		///// </summary> 
		//public string RemoteCode
		//{
		//    get
		//    {

		//        string remoteCode = HttpContext.User.FindFirstValue("remoteCode");
		//        if (remoteCode.IsNullOrEmpty())
		//        {
		//            return "";
		//        }
		//        else
		//        {
		//            return CommonHelper.ToString(remoteCode);
		//        }
		//    }
		//}
		/// <summary>
		/// 当前组织Id
		/// </summary>
		public long OrgId
		{
			get
			{

				string? org_id = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_ORGANIZATION);
				if (org_id == null ||  org_id.IsNullOrEmpty())
				{
					return 0;
				}
				else
				{
					return CommonHelper.ToInt64(org_id);
				}
			}
		}

		/// <summary>
		/// 真实姓名
		/// </summary>
		public string UserRealName
		{

			get
			{
				string? realName = HttpContext.User.FindFirstValue(JwtTokenConst.JWT_REAL_NAME);
				if (realName != null)
				{
					return realName;
				}
				return string.Empty;
			}
		}

		/// <summary>
		/// 删除用户信息缓存
		/// </summary>
		/// <param name="user_id">The user identifier.</param>
		public void RemoveUserInfoCache(long user_id)
		{
			CacheHelper.RemoveByStartsWith("APPUSER:" + user_id);
		}
		/// <summary>
		/// 当前用户信息
		/// </summary>
		public virtual UserInfo? UserInfo
		{
			get
			{
				if (UserId == 0)
				{
					return null;
				}
				long org_id = 0;
				long dep_id = 0;
				var userInfo = new UserInfo();
				userInfo.userId = UserId;
				string userInfoKey = "APPUSER:" + userInfo.userId.ToString() + "-" + this.OrgId.ToString();
				UserInfo newUserInfo = CacheHelper.Get<UserInfo>(userInfoKey);
				bool isSup = false;
				if (newUserInfo != null)
				{
					return newUserInfo;
				}
				else
				{
					var userDB = getUserDB();
					string sql = @"select u.user_id,u.nickname,u.realname,u.username,u.cususername,u.userpwd,
                                            u.salt,u.is_sup,u.user_type,u.org_id ,s.dep_id,u.need_change_pwd,
                                            u.staff_id,isnull(s.pos_id,0) as pos_id,u.u9pwd,u.can_remote,u.remote_end_date,u.remote_code
                                from sys_users u
                                     left join sys_staff s  on u.staff_id = s.staff_id
                                where u.user_id=@user_id";
					dynamic user = userDB.Sql(sql).Parameter("user_id", UserId).QuerySingle<dynamic>();

					if (user == null)
					{
						return null;
					}
					else
					{
						userInfo.userId = CommonHelper.ToInt64(user.user_id);
						org_id = this.OrgId;
						dep_id = CommonHelper.ToInt64(user.dep_id);
						userInfo.orgId = org_id;
						userInfo.depId = dep_id;
						userInfo.posId = CommonHelper.ToInt64(user.pos_id);
						userInfo.realName = CommonHelper.ToString(user.realname);
						userInfo.username = CommonHelper.ToString(user.username);
						userInfo.cususername = CommonHelper.ToString(user.cususername);
						userInfo.need_change_pwd = CommonHelper.ToInt(user.need_change_pwd);
						userInfo.staff_id = CommonHelper.ToInt(user.staff_id);
						userInfo.u9pwd = CommonHelper.ToString(user.u9pwd);
						userInfo.can_remote = CommonHelper.ToBool(user.can_remote, false);
						userInfo.remote_end_date = CommonHelper.ToDateTime(user.remote_end_date, DateTime.MinValue);
						userInfo.remote_code = CommonHelper.ToString(user.remote_code);
						isSup = CommonHelper.ToInt(user.is_sup) == 1;
					}

					try
					{
						string sqlOrg = @"select a.org_Id as org_Id,a.org_code as org_code,a.org_fullname,a.org_shortname,a.u9orgId from sys_orgs a
                where a.org_id = @org_id";
						dynamic orgInfo = userDB.Sql(sqlOrg).Parameter("org_id", this.OrgId).QuerySingle<dynamic>();
						if (orgInfo != null)
						{
							userInfo.orgId = CommonHelper.ToInt64(orgInfo.org_Id);
							userInfo.orgCode = CommonHelper.ToString(orgInfo.org_code);
							userInfo.u9orgId = CommonHelper.ToString(orgInfo.u9orgId);
							userInfo.orgName = CommonHelper.ToString(orgInfo.org_fullname);
							userInfo.orgShortName = CommonHelper.ToString(orgInfo.org_shortname);
						}
					}
					catch (Exception)
					{

					}
					#region 获取关联组织列表
					string sqlOrgs = @"SELECT o.org_id, o.org_fullname,org_shortname
FROM
(
  SELECT r.org_id
  FROM sys_user_role(nolock) r
  WHERE r.[user_id]  = @uid
  UNION
  SELECT r.org_id
  FROM sys_staff(nolock) r
  WHERE r.staff_id IN ( SELECT staff_id FROM sys_users WHERE [user_Id] = @uid  and is_delete=0 )
) a
JOIN sys_orgs(nolock) o ON a.org_id = o.org_id
where o.is_delete=0
ORDER BY o.org_code";
					try
					{
						dynamic orgs = userDB.Sql(sqlOrgs).Parameter("uid", userInfo.userId).QueryMany<dynamic>();
						userInfo.Orgs = orgs;
					}
					catch (Exception)
					{

					}
					#endregion

					string sqlDep = @"select dep_code,[dep_name] from sys_deps where [dep_id] =@dep_id ";
					List<dynamic> depList = userDB.Sql(sqlDep).Parameter("dep_id", dep_id).QueryMany<dynamic>();
					if (depList != null && depList.Count > 0)
					{
						userInfo.depCode = depList[0].dep_code;
						userInfo.depName = depList[0].dep_name;
					}

					string sqlDepName = @"SELECT dep_name
FROM (
select [dep_name]   from dbo.sys_deps_language where [dep_id] =@dep_id AND dep_name IS NOT NULL   AND language_code ='zh'
UNION all
select [dep_name] from dbo.sys_deps_language where [dep_id] =@dep_id AND dep_name IS NOT NULL  AND language_code ='en'
UNION all
select [dep_name] from dbo.sys_deps_language where [dep_id] =@dep_id AND dep_name IS NOT NULL AND language_code ='km'  
) a WHERE a.dep_name IS NOT NULL ";
					List<string> depNames = userDB.Sql(sqlDepName).Parameter("dep_id", dep_id).QueryMany<string>();
					if (depNames.Count > 0)
					{
						userInfo.depName = string.Join("/ ", depNames);
					}
					string sqlPos = @"SELECT [pos_id] ,[pos_name] ,[pos_code]  FROM  [dbo].[sys_position] where [pos_id] =@pos_id ";
					List<dynamic> posList = userDB.Sql(sqlPos).Parameter("pos_id", userInfo.posId).QueryMany<dynamic>();
					if (posList != null && posList.Count > 0)
					{
						userInfo.posCode = posList[0].pos_code;
						userInfo.posName = posList[0].pos_name;
					}


					IPermissionService? permissionsService = SXHttpContext.GetService<IPermissionService>();
					if (permissionsService != null)
					{
						if (isSup)
						{
							userInfo.permissions = permissionsService.GetAllPermission();
						}
						else
						{
							userInfo.permissions = permissionsService.GetPermission(userInfo.userId, this.OrgId);
						}
					}

					if (userInfo.permissions == null || userInfo.permissions.Count == 0)
					{
						userInfo.permissions = new List<string> { "Editor" };
					}
					userInfo.permissions = userInfo.permissions.Distinct().ToList();
					userInfo.IsSup = isSup;
					CacheHelper.Set(userInfoKey, userInfo);
					return userInfo;
				}
			}
		}
		/// <summary>
		/// 获取当前用户的DB
		/// </summary>
		/// <returns></returns>
		private IDbContext getUserDB()
		{
			string connStr = ConfigHelper.GetConn(this.UserSystem);
			if (connStr.IsNullOrEmpty())
			{
				connStr = ConfigHelper.GetConn("Default");
			}
			var userDb = new DbContext().ConnectionString(connStr, new SqlServerProvider());

			return userDb;
		}
		#endregion

	}
}
